import React, { Fragment, Component } from 'react';
import styles from './index.less';
import { connect } from 'dva';
import { Table, Popconfirm, Form, Button, Divider, Input, InputNumber, Radio, DatePicker } from 'antd';
import  AddTransactionForm from './AddTransactionForm';
import moment from 'moment';

const RadioGroup = Radio.Group;
const RadioButton = Radio.Button;
const FormItem = Form.Item;
const EditableContext = React.createContext();
const EditableRow = ({ form, index, ...props }) => (
    <EditableContext.Provider value={form}>
        <tr {...props} />
    </EditableContext.Provider>
);

const EditableFormRow = Form.create()(EditableRow);

const EditableCell = ({ ...props }) => {
    const { editing, dataIndex, title, inputType, record, index, editType, ...restProps } = props;
    const getInput = () => {
        if (inputType === 'number') {
            return <InputNumber />;
        } else if (inputType === 'radio') {
            return (
                <RadioGroup>
                    <RadioButton value={1}>现金</RadioButton>
                    <RadioButton value={2}>会员卡</RadioButton>
                </RadioGroup>
            );
        } else if (inputType === 'date') {
            return (
                <DatePicker
                    showTime
                    format="YYYY-MM-DD HH:mm:ss"
                />
            );
        }
        else { return <Input /> }
    };
    return (
        <EditableContext.Consumer>
            {(form) => {
                const { getFieldDecorator } = form;
                return (
                    <td {...restProps}>
                        {editing ? (
                            dataIndex !== 'phone' ? (
                                <FormItem style={{ margin: 0 }}>
                                    {getFieldDecorator(dataIndex, {
                                        rules: [{
                                            required: true,
                                            message: `请输入${title}!`,
                                        }],
                                        initialValue: record[dataIndex],
                                    })(getInput())}
                                </FormItem>) : (
                                <FormItem style={{ margin: 0 }}>
                                    {getFieldDecorator(dataIndex, {
                                        rules: [{
                                            required: true,
                                            message: `请输入${title}!`,
                                        },
                                        {
                                            pattern: /^1\d{10}$/,
                                            message: '手机号格式错误！',
                                        }
                                        ],
                                        initialValue: record[dataIndex],
                                    })(getInput())}
                                </FormItem>
                            )
                        ) : restProps.children}
                    </td>
                );
            }}
        </EditableContext.Consumer>
    );
};

@connect(({ user, loading }) => ({
    transactionList:user.transactionList,
    loading: loading.effects['user/editTransaction', 'user/deleteTransaction', 'user/queryTransaction'],
    loadingEdit: loading.effects['user/addTransaction'],
})) //eslint-disable-line
class UserList extends Component {
    state={
        visible: false,
        editingKey: '',
        editType: '',
        filteredInfo: null,
    }
    componentDidMount() {
        const { dispatch } = this.props;
        dispatch({
            type: 'user/queryTransaction'
        });
    }
    deleteUser(id) {
        const { dispatch } = this.props;
        dispatch({
            type: 'user/deleteTransaction',
            payload: id
        }).then(() => {
            this.setState({
                filteredInfo: null
            });
        });
    }
    handleAdd() {
        const { form } = this.formRef.props;
        const { dispatch } = this.props;
        form.validateFields((err, values) => {
            if (err) return;
            dispatch({
                type: 'user/addTransaction',
                payload: {
                    transaction: {
                        ...values, phone: Number(values.phone),
                        cost: Number(values.cost),
                        payMethod: Number(values.payMethod),
                        date: moment(values.date).format('YYYY-MM-DD hh:mm:ss')
                    }
                }
            }).then(() => {
                form.resetFields();
                this.setState({
                    visible: false,
                    filteredInfo: null
                });
                dispatch({
                    type: 'user/queryTransaction'
                });
            });
        });

    }
    handleChange(_, filters) {
        this.setState({
            filteredInfo: filters
        });
    }
    handleCancel() {
        this.setState({
            visible: false,
        });
    }
    showModal() {
        this.setState({
            visible: true
        });
    }
    saveFormRef = (formRef) => {
        this.formRef = formRef;
    }
    isEditing = (record) => {
        return record.id === this.state.editingKey;
    }
    edit(key, editType) {
        this.setState({
            editingKey: key,
            editType,
        });
    }
    save(form, record) {
        form.validateFields((error, row) => {
            if (error) { return }
            const { editType } = this.state;
            const { dispatch } = this.props;
            const { id } = record;
            if (editType === 'edit') {
                dispatch({
                    type: 'user/editTransaction',
                    payload: {
                        id,
                        transaction: {
                            ...row,
                            phone: Number(row.phone),
                            cost: Number(row.cost),
                            payMethod: Number(row.payMethod),
                            date: moment(row.date).format('YYYY-MM-DD hh:mm:ss')

                        }
                    }
                }).then(() => {
                    this.setState({
                        editingKey: '',
                        editType: '',
                        filteredInfo: null
                    });
                });
            }
        });
    }
    cancel=() => {
        this.setState({
            editingKey: '',
            editType: ''
        });
    }
    render() {
        const { transactionList, loading, loadingEdit } = this.props;
        const { visible, editType, filteredInfo = {}} = this.state;
        const dataSource = transactionList.map(item => ({
            ...item,
            date: moment(item.date, 'YYYY-MM-DD hh:mm:ss')
        }));
        const filters = transactionList.reduce((acc, next) => {
            const value = Number(moment(next.date, 'YYYY-MM-DD'));
            if (acc.indexOf(value) === -1) {
                acc.push(value);
            }
            return acc;
        }, []).map((item) => ({
            text: moment(item).format('YYYY-MM-DD'),
            value: item
        }));
        const components = {
            body: {
                row: EditableFormRow,
                cell: EditableCell,
            }
        };
        const columns = [{
            title: '手机',
            dataIndex: 'phone',
            key: 'phone',
            editable: true
        },
        {
            title: '类型',
            dataIndex: 'type',
            key: 'type',
            editable: true
        },
        {
            title: '交易金额',
            dataIndex: 'cost',
            key: 'cost',
            editable: true
        },
        {
            title: '时间',
            dataIndex: 'date',
            key: 'date',
            render: (text) => (<Fragment>{moment(text).format('YYYY-MM-DD hh:mm:ss')}</Fragment>),
            filters,
            filterMultiple: true,
            filteredValue: filteredInfo ? filteredInfo.date : null,
            onFilter: (value, record) => { return Number(moment(record.date.format('YYYY-MM-DD'), 'YYYY-MM-DD')) === Number(value) },
            editable: true
        },
        {
            title: '车牌',
            dataIndex: 'license',
            key: 'license',
            editable: true,
        },
        {
            title: '支付方式',
            dataIndex: 'payMethod',
            key: 'payMethod',
            render: (text) => (<Fragment>{Number(text) === 1 ? '现金支付' : Number(text) === 2 ? '会员卡支付' : '其他'}</Fragment>),
            editable: true,
        },
        {
            title: '操作',
            dataIndex: 'operation',
            width: 160,
            render: (text, record) => {
                const editable = this.isEditing(record);
                return (
                    <div>
                        {editable ? (
                            <span>
                                <EditableContext.Consumer>
                                    {form => (
                                        <a
                                            onClick={() => this.save(form, record)}
                                            style={{ marginRight: 8 }}
                                        >
                                            保存
                                        </a>
                                    )}
                                </EditableContext.Consumer>
                                <Popconfirm
                                    title="确定取消?"
                                    onConfirm={() => this.cancel(record.id)}
                                >
                                    <a>取消</a>
                                </Popconfirm>
                            </span>
                        ) : (
                            <Fragment>
                                <a onClick={() => this.edit(record.id, 'edit')}>修改</a>
                                <Divider type="vertical" />
                                <Popconfirm
                                    title={(<Fragment>确定删除交易?</Fragment>)}
                                    onConfirm={() => this.deleteUser(record.id)}
                                >
                                    <a>删除</a>
                                </Popconfirm>
                            </Fragment>
                        )}
                    </div>
                );
            },
        }
        ];
        const EditableColumns = columns.map((col) => {
            if (!col.editable) {
                return col;
            }
            return {
                ...col,
                onCell: record => ({
                    record,
                    inputType: col.dataIndex === 'cost' ? 'number' : col.dataIndex === 'payMethod' ? 'radio' : col.dataIndex === 'date' ? 'date' : 'text',
                    title: col.title,
                    dataIndex: col.dataIndex,
                    editing: this.isEditing(record),
                    editType,
                })
            };
        });
        return (
            <div className={styles.container}>
                <Button onClick={this.showModal.bind(this)} loading={loadingEdit} type="primary" style={{ marginBottom: 16 }}>
                    新增交易
                </Button>
                <Table
                    onChange={this.handleChange.bind(this)}
                    components={components}
                    bordered
                    loading={loading}
                    dataSource={dataSource}
                    columns={EditableColumns}
                    rowKey={(record) => record.id}
                ></Table>
                <AddTransactionForm
                    loading={loadingEdit}
                    wrappedComponentRef={this.saveFormRef.bind(this)}
                    visible={visible}
                    onCancel={this.handleCancel.bind(this)}
                    onCreate={this.handleAdd.bind(this)}
                >
                </AddTransactionForm>
            </div>
        );
    }
}

export default UserList;
